﻿/*  
	------------------------------------------------------------------------
	 NQ Software Development Kit Component
	
	 Homepage: http://www.awzhome.de/
	------------------------------------------------------------------------
	
	This Source Code Form is subject to the terms of the Mozilla Public
	License, v. 2.0. If a copy of the MPL was not distributed with this
	file, You can obtain one at http://mozilla.org/MPL/2.0/.
   
	The Original Code is code of NQ Software Development Kit Component.

	The Initial Developer of the Original Code is Andreas Weizel.
	Portions created by the Initial Developer are
	Copyright (C) 2012 Andreas Weizel. All Rights Reserved.
	
	Contributor(s): (none)
	
	------------------------------------------------------------------------
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AWZhome.NQ.CommonServices;
using NQCSServices = AWZhome.NQ.CommonServices.Services;
using NQsdkServices = AWZhome.NQsdk.Services;
using AWZhome.NQ.Core.Fluent;
using AWZhome.NQ.Core;
using AWZhome.NQsdk.Visual;
using AWZhome.NQsdk.Helpers;
using System.Windows.Controls;
using System.Windows;

namespace AWZhome.NQsdk.Services
{
	[NQExportedService]
	public class BarItemBrowserViewService : ViewServiceBase, Services.IBarItemBrowserViewService
	{
		private BarItemBrowserView _browserView;
		private string _displayName;
		private IBarManager _servBar;

		public BarItemBrowserViewService(ISession sessionService)
			: base(sessionService)
		{
		}

		protected override bool CheckSessionType(ISession session)
		{
			return true;
		}

		public override string DisplayName
		{
			get
			{
				return _displayName;
			}
		}

		public override bool IsChanged
		{
			get
			{
				return false;
			}
		}

		public override bool CanBeClosed
		{
			get
			{
				return true;
			}
		}

		public override bool IsLoggable
		{
			get
			{
				return false;
			}
		}

		public override bool IsDocument
		{
			get
			{
				return true;
			}
		}

		public override object DisplayedObject
		{
			get
			{
				return _browserView;
			}
		}

		public override System.Windows.Media.ImageSource Icon
		{
			get
			{
				return null;
			}
		}

		public override ViewDisplayMode DockingType
		{
			get
			{
				return ViewDisplayMode.InClientArea | ViewDisplayMode.Floating;
			}
		}

		protected override void OnViewManagerSet(IViewManager viewManager)
		{
			base.OnViewManagerSet(viewManager);

			// Get resource service
			INQResourceGUIManager servRes = ServiceCore
				.Get<NQCSServices.IResourceGUIService>()
				.To;
			_displayName = servRes.GetResString("NQsdk", "BarItemBrowserView.DisplayName");

			// Create visual view control and its BarService
			_browserView = new BarItemBrowserView();

			if ((viewManager != null)
							&& (viewManager.Container != null)
							&& (viewManager.Container.BarService != null))
			{
				_servBar = viewManager.Container.BarService;
				var rootItem = this.FillTree();
				_browserView.DataContext = new ThisContainerTreeItem[] { rootItem };

				_browserView.BarItemTreeView.SelectedItemChanged += BarItemTreeView_SelectedItemChanged;
				_browserView.BarItemTreeView.Loaded += (s, e) =>
					{
						// Activate root item initially
						TreeViewItem rootTreeViewItem =
							_browserView.BarItemTreeView.ItemContainerGenerator.ContainerFromItem(rootItem) as TreeViewItem;
						if (rootTreeViewItem != null)
						{
							rootTreeViewItem.IsSelected = true;
						}
					};
			}
		}

		public override void LoadContents()
		{
			base.LoadContents();

			// Read settings
			IPersistManager servPersist = ServiceCore
				.Get<NQCSServices.IPersistService>()
				.To;
			ConfigData splitterPos = servPersist.GetSetting("NQsdk", "barItemBrowserSplitterPos", true);

			if (splitterPos != null)
			{
				_browserView.InnerTreeGrid.ColumnDefinitions[1].Width =
					(GridLength) (new GridLengthConverter()).ConvertFromString(splitterPos.AsString());
			}
		}

		public override void SaveContents(ViewSaveReason saveReason)
		{
			base.SaveContents(saveReason);

			// Save the settings
			IPersistManager servPersist = ServiceCore
				.Get<NQCSServices.IPersistService>()
				.To;
			servPersist.SetSetting("NQsdk", "barItemBrowserSplitterPos",
				new ConfigData().FromString((new GridLengthConverter()).ConvertToString(_browserView.InnerTreeGrid.ColumnDefinitions[1].Width).Replace("*", "")), true);
		}

		/// <summary>
		/// Builds the data objects for the tree view of the browser.
		/// </summary>
		/// <returns>The root tree item.</returns>
		private ThisContainerTreeItem FillTree()
		{
			// Create root item
			ThisContainerTreeItem rootItem = new ThisContainerTreeItem();

			// Create tree items for (all items) and the real bands
			BarBandTreeItem allItems = new BarBandTreeItem();
			allItems.IsNamedBand = false;
			string[] allBarItemKeys = _servBar.GetItemKeys();
			if (allBarItemKeys != null)
			{
				allItems.BarItems = allBarItemKeys.Select(
						key => new BarItemTreeItem()
						{
							ItemObject = _servBar.GetItem(key),
							BarItems = this.FillItemContainer(_servBar.GetItem(key)),
						}
					);
			}
			rootItem.Bands.Add(allItems);

			string[] allBandKeys = _servBar.GetBandKeys();
			if (allBandKeys != null)
			{
				rootItem.Bands.AddRange(allBandKeys.Select(
						key => new BarBandTreeItem()
						{
							BandObject = _servBar.GetBand(key),
							BarItems = this.FillItemContainer(_servBar.GetBand(key)),
							IsNamedBand = true
						}
					));
			}

			// Add menu band, if available
			IBarBand menuBand = _servBar.GetMenuBand();
			if (menuBand != null)
			{
				rootItem.Bands.Add(
					new BarBandTreeItem()
					{
						BandObject = menuBand,
						BarItems = this.FillItemContainer(menuBand),
						IsNamedBand = true
					});
			}

			return rootItem;
		}

		/// <summary>
		/// Creates an enumeration of children tree items for a INQBarItemContainer (i.e. band or item).
		/// </summary>
		/// <param name="itemContainer">Instance of the <see cref="AWZhome.NQ.CommonServices.IBarItemContainer"/>.</param>
		/// <returns>Enumeration of tree items.</returns>
		private IEnumerable<BarItemTreeItem> FillItemContainer(IBarItemContainer itemContainer)
		{
			if (itemContainer != null)
			{
				string[] childItemKeys = itemContainer.GetItemKeys();
				if (childItemKeys != null)
				{
					return childItemKeys.Select(
							key => new BarItemTreeItem()
							{
								ItemObject = _servBar.GetItem(key),
								BarItems = this.FillItemContainer(_servBar.GetItem(key))
							}
						);
				}
				else
				{
					return new BarItemTreeItem[0];
				}
			}
			else
			{
				return new BarItemTreeItem[0];
			}
		}

		private void BarItemTreeView_SelectedItemChanged(object sender, System.Windows.RoutedPropertyChangedEventArgs<object> e)
		{
			object selectedItem = _browserView.BarItemTreeView.SelectedItem;
			if (selectedItem != null)
			{
				if ((selectedItem is BarBandTreeItem) && ((BarBandTreeItem) selectedItem).IsNamedBand)
				{
					// A band has been selected in tree view
					_browserView.thisContainerPropertiesGrid.Visibility = System.Windows.Visibility.Hidden;
					_browserView.thisContainerPropertiesGrid.DataContext = null;
					_browserView.barBandPropertiesGrid.Visibility = System.Windows.Visibility.Visible;
					_browserView.barBandPropertiesGrid.DataContext = selectedItem;
					_browserView.barItemPropertiesGrid.Visibility = System.Windows.Visibility.Hidden;
					_browserView.barItemPropertiesGrid.DataContext = null;
				}
				else if (selectedItem is BarItemTreeItem)
				{
					// A band has been selected in tree view
					_browserView.thisContainerPropertiesGrid.Visibility = System.Windows.Visibility.Hidden;
					_browserView.thisContainerPropertiesGrid.DataContext = null;
					_browserView.barBandPropertiesGrid.Visibility = System.Windows.Visibility.Hidden;
					_browserView.barBandPropertiesGrid.DataContext = null;
					_browserView.barItemPropertiesGrid.Visibility = System.Windows.Visibility.Visible;
					_browserView.barItemPropertiesGrid.DataContext = selectedItem;
				}
				else if ((selectedItem is ThisContainerTreeItem)
					|| ((selectedItem is BarBandTreeItem) && !((BarBandTreeItem) selectedItem).IsNamedBand))
				{
					// "This container" has been selected in tree view
					_browserView.thisContainerPropertiesGrid.Visibility = System.Windows.Visibility.Visible;
					_browserView.thisContainerPropertiesGrid.DataContext = selectedItem;
					_browserView.barItemPropertiesGrid.Visibility = System.Windows.Visibility.Hidden;
					_browserView.barItemPropertiesGrid.DataContext = null;
					_browserView.barBandPropertiesGrid.Visibility = System.Windows.Visibility.Hidden;
					_browserView.barBandPropertiesGrid.DataContext = null;
				}
			}
		}
	}
}
